x86/stack: avoid peeking into unmapped guard pages when dumping Xens stack
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 9 Jan 2015 16:24:23 +0000 (17:24 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 9 Jan 2015 16:24:23 +0000 (17:24 +0100)
commitc9a206331067ace6416692c64c44375d51e25180
tree24a2bf8e406d9866677068c04a42242f00574b28
parentd2ee7b0fca1f8ff045ef66c9ebbc032faaad4a0c
x86/stack: avoid peeking into unmapped guard pages when dumping Xens stack

Currently, Xens stack tracing and dumping of its own stacks will always
attempt to continue to the top of the primary stack.  While this is fine for
99% of cases, it is incorrect when the stack pointer starts on an IST stack.

In particular, the stack analysis functions will wander up from the IST
stacks, through the syscall trampolines and then onto the primary stack.  If
MEMORY_GUARD is enabled, this will cause a pagefault when attempting to read
from the guard page.  Being an unhandled hypervisor fault, the pagefault
handler will then attempt to dump the stacks, and fall over the same problem.

This change introduces more finegrained knowledge of the cpu stack layouts,
and introduces different boundaries for whether the stack pointer is on an IST
stack or the primary stack.  Stack analysis starting from an IST stack will
now never exceed the stack they start on, and specifically not spill over into
an adjacent IST stack, or the syscall trampoline area.

A sample now looks like:
(XEN) '1' pressed -> testing mce stack printing
(XEN) ----[ Xen-4.5.0-rc  x86_64  debug=n  Not tainted ]----
(XEN) CPU:    0
(XEN) RIP:    e008:[<ffff82d08019196b>] check_mce_test+0xb/0x20
(XEN) RFLAGS: 0000000000010002   CONTEXT: hypervisor
(XEN) rax: 0000000000000000   rbx: ffff82d0802caf58   rcx: 0000000000000000
(XEN) rdx: ffff82d080235d20   rsi: 000000000000000a   rdi: ffff82d0802caf58
(XEN) rbp: 0000000000000031   rsp: ffff82d0802caf40   r8:  ffff83007faf4000
(XEN) r9:  0000000000004000   r10: 0000000000000001   r11: 0000000000000006
(XEN) r12: ffff82d0802cfe58   r13: ffff82d0802cfe58   r14: dead0000c0de0000
(XEN) r15: ffff82d080191910   cr0: 000000008005003b   cr4: 00000000000026f0
(XEN) cr3: 0000000062565000   cr2: 00007fb98a5e8fe8
(XEN) ds: 0000   es: 0000   fs: 0000   gs: 0000   ss: e010   cs: e008
(XEN) Xen stack trace from rsp=ffff82d0802caf40:
(XEN)    ffff82d0801ad119 ffff82d080278da0 ffff82d080227907 ffff82d080191910
(XEN)    dead0000c0de0000 ffff82d0802cfe58 ffff82d0802cfe58 0000000000000031
(XEN)    ffff82d080278da0 0000000000000006 0000000000000001 0000000000004000
(XEN)    ffff83007faf4000 ffff82d0803101a0 0000000000000000 ffff82d0802c8000
(XEN)    000000000000000a ffff82d080277620 0000001200000000 ffff82d08018ae6a
(XEN)    000000000000e008 0000000000000292 ffff82d0802cfd18 000000000000e010
(XEN) Xen call trace:
(XEN)    [<ffff82d08019196b>] check_mce_test+0xb/0x20
(XEN)    [<ffff82d0801ad119>] do_machine_check+0x9/0x20
(XEN)    [<ffff82d080227907>] handle_ist_exception+0x8d/0xf6
(XEN)

In this test case, %r15 is deliberately set up with a function pointer in an
attempt to fool the naive stack trace algorithm.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/traps.c
xen/include/asm-x86/current.h